共计 2113 个字符,预计需要花费 6 分钟才能阅读完成。
前言
日常开发过程中,我们程序猿更多时候会自嘲CV工具人
,这是因为在业务逻辑开发时,重复代码太多了,如果真的要去全盘Copy
的话,会显得很Low
,这样我们就会想到复用代码,既省时又简洁。
那我们这里就会提及复用类的两种方法:①组合、②继承
组合
语法
将对象引用置于新类成员变量位置;
/**
* @author plm
* @create 2021/3/4 23:01
*/
class Pen {
private String s;
public Pen() {
System.out.println("Pen Construct.");
s = "Construct"; // 在类的构造器中
}
@Override
public String toString() {
return "Pen{" +
"s='" + s + '\'' +
'}';
}
}
public class Desk {
private String
s1 = "World", // 在定义对象的地方
s2 = "Peace",
s3,
s4;
private Pen pen;
private int i;
private float f;
public Desk() {
System.out.println("Desk Construct.");
s3 = "Hello";
f = 2.43F;
pen = new Pen();
}
{
i = 45; // 使用实例初始化
}
@Override
public String toString() {
if (s4 == null) {
s4 = "Hi"; // 惰性初始化(懒加载)
}
return "Desk{" +
"s1='" + s1 + '\'' +
", s2='" + s2 + '\'' +
", s3='" + s3 + '\'' +
", s4='" + s4 + '\'' +
", pen=" + pen +
", i=" + i +
", f=" + f +
'}';
}
public static void main(String[] args) {
Desk desk = new Desk();
System.out.println(desk.toString());
}
}
/* 输出
Desk Construct.
Pen Construct.
Desk{s1='World', s2='Peace', s3='Hello', s4='Hi', pen=Pen{s='Construct'}, i=45, f=2.43}
*/
初始化时机
如上代码,有以下几处位置:
在定义对象的地方;(总是可以在构造方法被调用之前初始化)
在类的构造方法中;
在使用到对象之前才会初始化,称为惰性初始化;(不必每次new对象就初始化,可以减少额外的开销)
使用实例初始化;
继承
语法
关键字extends
,从现有类获得继承信息(所有的域和方法)构建出新类;
/**
* @author plm
* @create 2021/3/4 23:40
*/
class Dword {
public Dword() {
System.out.println("Dword Construct.");
}
void dp() {
System.out.println("dp.");
}
}
class Nword extends Dword {
public Nword(int i) {
System.out.println("Nword Construct.");
}
void dp_1() {
System.out.println("dp_1.");
}
}
public class Sword extends Nword {
private int i = 7;
public Sword(int i) {
super(i);
System.out.println("Sword Construct.");
}
void dp_2() {
super.dp();
super.dp_1();
System.out.println("dp_2.");
}
public static void main(String[] args) {
Sword sword = new Sword(6);
sword.dp();
sword.dp_1();
sword.dp_2();
}
}
/* 输出
Dword Construct.
Nword Construct.
Sword Construct.
dp.
dp_1.
dp.
dp_1.
dp_2.
*/
tips:supper
关键字表示超类,想要调用基类的方法可使用supper.基类方法名()即可;
初始化基类
导出类进行初始化时,会先调用supper
调用基类的构造方法进行初始化(此为隐式地调用基类的无参构造);
基类在导出类访问它之前就已经完成了初始化;
带参的构造方法
必须使用关键supper
显示地调用基类构造方法(如上代码),否则编译器就会提醒你:
There is no default constructor available in ‘cn.peiluming.test2.test1.Nword’
方法重写
既然子类拥有了父类的所有方法,那如果需要对父类方法进行自定义实现,这里就会涉及到重写,也是后面多态的前提之一
JDK 1.5 之后引入注解@Override
,对你的重写方法进行校验;
组合与继承如何选择
组合一般多用于Has-a
,在新的类中使用现有类的属性,而并非它的方法;多加上private
修饰符!
继承多用于Is-a
,常常结合向上转型使用,因为继承可以确保基类中的方法,在导出类中同样生效;